home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / flash-0.4.3 / lib / program.cc < prev    next >
C/C++ Source or Header  |  1999-01-01  |  9KB  |  461 lines

  1. /////////////////////////////////////////////////////////////
  2. // Flash Plugin and Player
  3. // Copyright (C) 1998,1999 Olivier Debon
  4. // 
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. // 
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. // 
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18. // 
  19. ///////////////////////////////////////////////////////////////
  20. //  Author : Olivier Debon  <odebon@club-internet.fr>
  21. //  
  22.  
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include "program.h"
  26. #include "displaylist.h"
  27. #include "graphic.h"
  28. #include "sound.h"
  29.  
  30. #define NOTHING  0x0
  31. #define WAKEUP   0x1
  32. #define GOTO     0x2
  33. #define REFRESH  0x4
  34.  
  35. static char *rcsid = "$Id: program.cc,v 1.17 1999/02/14 22:05:15 olivier Exp $";
  36.  
  37. #define PRINT 0
  38.  
  39. int debug = 0;
  40.  
  41. Program::Program(long n)
  42. {
  43.     long f;
  44.  
  45.     dl = new DisplayList;
  46.  
  47.     nbFrames = n;
  48.     frames = new Frame[n];
  49.     currentFrame = 0;
  50.     nextFrame = currentFrame;
  51.     getUrl = ( void (*)(char *,char *, void *))0;
  52.     getUrlClientData = 0;
  53.     for(f = 0; f < n; f++)
  54.     {
  55.         frames[f].controls = 0;
  56.         frames[f].label = "";
  57.     }
  58.  
  59.     movieStatus = MoviePlay;
  60.     refresh = 1;
  61.     sprite = 0;
  62.     settings = 0;
  63. }
  64.  
  65. Program::~Program()
  66. {
  67.     delete dl;
  68.     delete frames;
  69. }
  70.  
  71. Frame    *
  72. Program::getFrames()
  73. {
  74.     return frames;
  75. }
  76.  
  77. long
  78. Program::getNbFrames()
  79. {
  80.     return nbFrames;
  81. }
  82.  
  83. DisplayList *
  84. Program::getDisplayList()
  85. {
  86.     return dl;
  87. }
  88.  
  89. void
  90. Program::gotoFrame(long frame)
  91. {
  92.     long f;
  93.  
  94.     dl->clearList();
  95.  
  96.     for(f=0; f <= frame; f++) {
  97.         runFrame(0, 0, f, 0);
  98.     }
  99. }
  100.  
  101. long
  102. Program::runFrame(GraphicDevice *gd, SoundMixer *sm, long f, long action)
  103. {
  104.     Control        *ctrl;
  105.     Character    *character;
  106.     Matrix        *matrix;
  107.     Cxform        *cxform;
  108.     long         status = NOTHING;
  109.     long         update = 0;
  110.  
  111. #if PRINT&1
  112.     if (action) printf("Prog %x : Frame N° %d\n", this, f);
  113. #endif
  114.     for(ctrl = frames[f].controls; ctrl; ctrl = ctrl->next)
  115.     {
  116.         switch (ctrl->type)
  117.         {
  118.             case ctrlPlaceObject:
  119.             case ctrlPlaceObject2:
  120.                 character = 0;
  121.                 matrix = 0;
  122.                 cxform = 0;
  123.                 if (ctrl->flags & placeHasCharacter) {
  124.                     character = ctrl->character;
  125.                 }
  126.                 if (ctrl->flags & placeHasMatrix) {
  127.                     matrix = &ctrl->matrix;
  128.                 }
  129.                 if (ctrl->flags & placeHasColorXform) {
  130.                     cxform = &ctrl->cxform;
  131.                 }
  132.                 if (!ctrl->clipDepth) {    // Ignore
  133.                     dl->placeObject(character, ctrl->depth, matrix, cxform);
  134.                     update = 1;
  135.                 }
  136.                 break;
  137.             case ctrlRemoveObject:
  138.                 character = ctrl->character;
  139.  
  140.                 if (!character) break;    // Should not happen
  141.  
  142.                 dl->removeObject(character, ctrl->depth);
  143.                 if (action) {
  144.                     if (character->hasEventHandler()) {
  145.                         gd->clearHitTest(character->getTagId());
  146.                     }
  147.                     character->reset();
  148.                     update = 1;
  149.                 }
  150.                 break;
  151.             case ctrlRemoveObject2:
  152.                 character = dl->removeObject(ctrl->depth);
  153.                 if (character && action) {
  154.                     if (character->hasEventHandler()) {
  155.                         gd->clearHitTest(character->getTagId());
  156.                     }
  157.                     character->reset();
  158.                     update = 1;
  159.                 }
  160.                 break;
  161.         // Actions
  162.             case ctrlDoAction:
  163.                 if (action) {
  164.                     status = doAction(ctrl->actionRecords, sm);
  165.                 }
  166.                 break;
  167.             case ctrlStartSound:
  168.                 if (action && sm) {
  169.                     sm->startSound( (Sound *)ctrl->character );
  170.                 }
  171.                 break;
  172.             case ctrlStopSound:
  173.                 if (action && sm) {
  174.                     sm->stopSounds();
  175.                 }
  176.                 break;
  177.             case ctrlBackgroundColor:
  178.                 dl->setBackgroundColor(&ctrl->color);
  179.                 if (action) {
  180.                     gd->setBackgroundColor(ctrl->color);
  181.                 }
  182.                 break;
  183.         }
  184.     }
  185.     if (status & GOTO) {
  186.         gotoFrame(nextFrame);
  187.         if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
  188.         update = 1;
  189.     }
  190.  
  191. #if PRINT&1
  192.     if (action) printf("Frame N° %d ready\n", f);
  193. #endif
  194.     return update;
  195. }
  196.  
  197. long
  198. Program::nestedMovie(GraphicDevice *gd, SoundMixer *sm, Matrix *mat)
  199. {
  200.     if (movieStatus == MoviePlay) {
  201.         // Movie Beeing Played
  202.         advanceFrame();
  203.         if (currentFrame == 0) {
  204.             dl->clearList();
  205.         }
  206.         runFrame(gd, sm, currentFrame);
  207.         if (nbFrames == 1) {
  208.             pauseMovie();
  209.         }
  210.     }
  211.  
  212.     sprite = dl->render(gd,mat);
  213.  
  214.     return (sprite || movieStatus == MoviePlay);
  215. }
  216.  
  217. long
  218. Program::processMovie(GraphicDevice *gd, SoundMixer *sm )
  219. {
  220.     long    soundReady;
  221.  
  222.     soundReady = sm->playSounds();
  223.  
  224. #if PRINT&1
  225.     printf("Prog %x : Current = %d     Next = %d\n", this, currentFrame, nextFrame);
  226. #endif
  227.  
  228.     if (movieStatus == MoviePlay) {
  229.         // Movie Beeing Played
  230.         advanceFrame();
  231.         if (currentFrame == 0) {
  232.             gd->resetHitTest();
  233.             dl->clearList();
  234.         }
  235.         refresh |= runFrame(gd, sm, currentFrame);
  236.         if (nextFrame == nbFrames && ((settings & PLAYER_LOOP) == 0)) {
  237.             pauseMovie();
  238.         }
  239.     }
  240.  
  241.     if (sprite || refresh) {
  242.         gd->clearCanvas();
  243.         sprite = dl->render(gd);
  244.         refresh = 0;
  245.         gd->displayCanvas();
  246.     }
  247.  
  248.     return (sprite || movieStatus == MoviePlay || soundReady);
  249. }
  250.  
  251. long
  252. Program::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event)
  253. {
  254.     ActionRecord    *action;
  255.     long         status = NOTHING;
  256.  
  257.     if (event) {
  258.         if (event->type == FeRefresh) {
  259.             gd->displayCanvas();
  260.         } else
  261.         if (event->type == FeNone) {
  262.             return 0;
  263.         } else {
  264.             action = dl->processEvent(gd,event);
  265.             status = doAction(action, sm);
  266.             if (status & REFRESH) {
  267.                 status |= WAKEUP;
  268.                 refresh = 1;
  269.             }
  270.             if (status & GOTO) {
  271.                 gd->resetHitTest();
  272.                 gotoFrame(nextFrame);
  273.                 if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
  274.                 refresh = 1;
  275.             }
  276.         }
  277.     }
  278.     if (status) return processMovie(gd,sm);
  279.     return 0;
  280. }
  281.  
  282. long
  283. Program::doAction(ActionRecord *action, SoundMixer *sm)
  284. {
  285.     long status = NOTHING;
  286.  
  287.     while(action)
  288.     {
  289.         switch (action->action)
  290.         {
  291.             case ActionPlaySound:
  292. #if PRINT&2
  293.                 printf("Prog %x : PlaySound\n", this);
  294. #endif
  295.                 sm->startSound(action->sound);
  296.                 status |= WAKEUP;
  297.                 break;
  298.             case ActionRefresh:
  299. #if PRINT&2
  300.                 printf("Prog %x : Refresh\n", this);
  301. #endif
  302.                 status |= REFRESH;
  303.                 break;
  304.             case ActionGotoFrame:
  305. #if PRINT&2
  306.                 printf("Prog %x : GotoFrame %d\n", this, action->frameIndex);
  307. #endif
  308.                 nextFrame = action->frameIndex;
  309.                 status |= WAKEUP|GOTO;
  310.                 break;
  311.             case ActionGetURL:
  312. #if PRINT&2
  313.                 printf("Prog %x : GetURL %s target = %s\n", this, action->url, action->target);
  314. #endif
  315.                 if (getUrl) {
  316.                     getUrl(action->url, action->target, getUrlClientData);
  317.                 }
  318.                 break;
  319.             case ActionNextFrame:
  320.                 nextFrame = currentFrame+1;
  321.                 status |= WAKEUP;
  322.                 break;
  323.             case ActionPrevFrame:
  324.                 nextFrame = currentFrame-1;
  325.                 status |= WAKEUP|GOTO;
  326.                 break;
  327.             case ActionPlay:
  328. #if PRINT&2
  329.                 printf("Prog %x : Play\n", this);
  330. #endif
  331.                 movieStatus = MoviePlay;
  332.                 if (currentFrame == nextFrame) advanceFrame();
  333.                 status |= WAKEUP;
  334.                 break;
  335.             case ActionStop:
  336. #if PRINT&2
  337.                 printf("Prog %x : Stop\n", this);
  338. #endif
  339.                 movieStatus = MoviePaused;
  340.                 nextFrame = currentFrame;
  341.                 break;
  342.             case ActionToggleQuality:
  343.                 break;
  344.             case ActionStopSounds:
  345.                 sm->stopSounds();
  346.                 break;
  347.             case ActionWaitForFrame:
  348.                 break;
  349.             case ActionSetTarget:
  350.                 break;
  351.             case ActionGoToLabel:
  352. #if PRINT&2
  353.                 printf("Prog %x : GotoFrame '%s'\n", this, action->frameLabel);
  354. #endif
  355.                 nextFrame = searchFrame(action->frameLabel);
  356.                 status |= WAKEUP|GOTO;
  357.                 break;
  358.         }
  359.         action = action->next;
  360.     }
  361.     return status;
  362. }
  363.  
  364. void
  365. Program::setCurrentFrameLabel(char *label)
  366. {
  367.     frames[currentFrame].label = label;
  368. }
  369.  
  370. void
  371. Program::rewindMovie()
  372. {
  373.     currentFrame = 0;
  374.     nextFrame = 0;
  375. }
  376.  
  377. void
  378. Program::pauseMovie()
  379. {
  380.     movieStatus = MoviePaused;
  381.     nextFrame = currentFrame;
  382. }
  383.  
  384. void
  385. Program::continueMovie()
  386. {
  387.     movieStatus = MoviePlay;
  388. }
  389.  
  390. void
  391. Program::nextStepMovie()
  392. {
  393.     if (movieStatus == MoviePaused) {
  394.         advanceFrame();
  395.     }
  396. }
  397.  
  398. void
  399. Program::advanceFrame()
  400. {
  401.     currentFrame = nextFrame;
  402.     nextFrame = currentFrame+1;
  403.     if (currentFrame == nbFrames) {
  404.         currentFrame = 0;
  405.         nextFrame = 1;
  406.     }
  407. }
  408.  
  409. void Program::setCurrentFrame(long n)
  410. {
  411.     currentFrame = n;
  412.     nextFrame = n;
  413.     refresh = 1;
  414. }
  415.  
  416. long Program::getFrame()
  417. {
  418.     return currentFrame;
  419. }
  420.  
  421. void
  422. Program::addControlInCurrentFrame(Control *ctrl)
  423. {
  424.     Control *c;
  425.  
  426.     ctrl->next = 0;
  427.     if (frames[currentFrame].controls == 0) {
  428.         frames[currentFrame].controls = ctrl;
  429.     } else {
  430.         for(c = frames[currentFrame].controls; c->next; c = c->next);
  431.         c->next = ctrl;
  432.     }
  433. }
  434.  
  435. void
  436. Program::setGetUrlMethod( void (*func)(char *, char *, void *), void *clientData)
  437. {
  438.     getUrl = func;
  439.     getUrlClientData = clientData;
  440. }
  441.  
  442. void
  443. Program::modifySettings(long flags)
  444. {
  445.     settings = flags;
  446. }
  447.  
  448. long
  449. Program::searchFrame(char *label)
  450. {
  451.     long f;
  452.  
  453.     for(f=0; f < nbFrames; f++)
  454.     {
  455.         if (frames[f].label && !strcmp(label,frames[f].label)) {
  456.             return f;
  457.         }
  458.     }
  459.     return 0;
  460. }
  461.